from contextlib import asynccontextmanager

import uvicorn
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
from sqlmodel import SQLModel
from fastapi.middleware.cors import CORSMiddleware
from starlette.staticfiles import StaticFiles

from .core.config import settings
from .core.database import engine
from .api.v1 import auth,permissions,dashboard,user

from fastapi import FastAPI
# 导入进来是为了读到模型，在启动时会创建数据库表
from .models.permission import (
    User,Role,Permission,Menu,
    UserRole,RolePermission,MenuPermission
)

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 在启动时执行
    SQLModel.metadata.create_all(engine)
    yield


app = FastAPI(
    docs_url=None, redoc_url=None,
    title="FastAPI Vue 权限管理系统",
    description="基于FastAPI和Vue的前后端分离权限管理系统",
    version="1.0.0",
    lifespan=lifespan
)

# 静态文件挂载（路由与静态文件映射）
app.mount("/static", StaticFiles(directory="app/statics"), name="static")


# 允许源列表
origins = ["http://localhost:5173", "http://127.0.0.1:5173"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 指定我们允许的源列表
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 重新提供一个Swagger UI，相当于我们自己重写了这么一个路由
@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )

# 这里与Swagger UI一样，重新提供Redoc
@app.get("/redoc", include_in_schema=False)
def custom_redoc():
    return get_redoc_html(
        openapi_url = "/openapi.json",
        title = "Redoc for FastAPI",
        redoc_js_url="/static/redoc.standalone.js"
    )


# 包含路由
app.include_router(auth.router, prefix="/api/v1")
app.include_router(permissions.router, prefix="/api/v1")
app.include_router(dashboard.router, prefix="/api/v1")
app.include_router(user.router, prefix="/api/v1")


@app.get("/")
async def root():
    return {"message": "欢迎使用FastAPI Vue权限管理系统"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000,reload=settings.DEBUG)